/**
 * 
 */
package criteres;

import java.util.Vector;

import org.apache.commons.math.complex.Complex;

import org.apache.commons.math.transform.FastFourierTransformer;


import general.*;
import gui.TextArea;

/**
 * Classe permettant de lancer le calcul du critere sur l'URL
 * @author remi
 *@version 1.0
 */
public class CritereURL {


	public static int kCoefAGarder=10;


	/**
	 * Permet de lancer le calcul du criter URL qui va transformer une URL en suite numerique, puis calculer la FFT et garder un nombre de coefficient egal à {@link #kCoefAGarder}
	 * @param pages le vecteur de page dont on veut calculer le critere URL
	 * @return vrai ou faux si erreur
	 */
	public static boolean calculCritereURL(Vector<Page> pages){
		// TODO : calculCritereURL : a tester

		//boucle sur les pages 
		//convertie l'URL en vecteur de float
		//sort les k premiers coef de la fft

		for(int i = 0; i < pages.size();i++){
			TextArea.ecrireMsg("calcul du critere URL de la page :" +i+" sur "+pages.size());
			calculCritereURL(pages.get(i));
			
		}
		
		return true;
	}

	/**
	 * Permet de lancer le calcul du criter URL d'UNE SEULE PAGE qui va transformer une URL en suite numerique, puis calculer la FFT et garder un nombre de coefficient egal à {@link #kCoefAGarder}
	 * @param page lla page dont on veut calculer le critere URL
	 * @return vrai ou faux si erreur
	 */
	public static boolean calculCritereURL(Page page){


		//boucle sur les pages 
		//convertie l'URL en vecteur de float
		//sort les k premiers coef de la fft


			Point pointBrut = new Point();
	
			pointBrut.setCriteresURL(
					extraireCoefFFT(
							urlTolFoatVector(
									page.getUrlLocal()
							)
					) 
			);
			// FIXME Attention, c'est normalement PointBrut ici
			page.setPoint(pointBrut);
			page.setPointBrut(pointBrut);

		
		return true;
	}
	
	/**
	 * Permet de convertir une URL en suite numerique, eventuellement en enlevant une partie de l'url (http , etc )
	 * @param url
	 * @return un vecteur de float contenant la suite de float correspondant a la conversion de l'URL
	 */
	public static Vector<Float> urlTolFoatVector(String url){
		// TODO urlToAscii : ...
		Vector<Float> retour = new Vector<Float>();


		for(int i = 0;i< url.length();i++){//on rempli le vecteur retour avec la conversion en float des char du string
			retour.add((float) url.charAt(i));
		}


		if(url.length()==0){
			retour.add( new Float(0));
		}
		return retour;
	}

	/**
	 * Calcul à partir d'une suite de nombre la fft de ces nombres et garde les {@link #kCoefAGarder} premiers coeficients pour les garder
	 * @param vecteurFloatIn la suite de nombre dont on veut calculer la fft
	 * @return les {@link #kCoefAGarder} coefficients de la fft qu'on veut garder
	 */
	public static Vector<Float> extraireCoefFFT(Vector<Float> vecteurFloatIn){

		Vector<Float> coefficientsGardes = new Vector<Float>();
		if(vecteurFloatIn.size()==0){coefficientsGardes.add(new Float(0));
		return coefficientsGardes;}

		//on calcul la valeur de l'exposant de la puissance de deux le plus proche de la taille du vecteur d'entree
		Double exposant = Math.log( (double) vecteurFloatIn.size())/Math.log(2);
		if(exposant > exposant.intValue() ){
			exposant = exposant+1;
		}
		exposant = (double) exposant.intValue();
		//on va ajuster la taille de vecteurFloatIn a une puissance de 2
		int tailleInitiale = vecteurFloatIn.size();
		for(int i=0;i < Math.pow(2, exposant)-tailleInitiale;i++){
			vecteurFloatIn.add((float) 0.0);
		}
		
		
		
		

		FastFourierTransformer fft = new FastFourierTransformer();//utilisation de la lib externe
		

		double[] tableauDouble = new double[vecteurFloatIn.size()];//le tableau sur lesquel serront effectué les calculs

		for(int i = 0;i<vecteurFloatIn.size();i++){//on converti le vecteur de float en un tableua de doubles
			tableauDouble[i] = (double) vecteurFloatIn.get(i);
		}

		
		Complex[] resultatsFFT = fft.transform(  tableauDouble); // le resultat du calcul de la fft
		

		
		
		
		for(int i = 0;i< Math.min(vecteurFloatIn.size(),kCoefAGarder);i++){//on rempli le vecteur de sortie
			coefficientsGardes.add((float) resultatsFFT[i].getReal());
		}

		//on complete le resultat avec des 0 pour avoir une taille au moins superieur a celle de kcoefAGArder
		while(coefficientsGardes.size() < CritereURL.kCoefAGarder){
			coefficientsGardes.add((float) 0.0);
			
		}

		return coefficientsGardes;
	}


	/**
	 * Constructeur classique
	 */
	public CritereURL() {
		// TODO Attention, la valeur de KcoefAGArder doit etre fixée par l'interface

	}

}
